home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / hurd / hurdmsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-18  |  9.5 KB  |  425 lines

  1. /* Copyright (C) 1992, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <hurd.h>
  20. #include <hurd/msg_server.h>
  21. #include <hurd/fd.h>
  22. #include <unistd.h>
  23. #include <limits.h>
  24. #include <string.h>
  25.  
  26.  
  27. #define AUTHCHECK \
  28.   if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \
  29.     return EPERM
  30.  
  31.  
  32. /* Snarfing and frobbing the init ports.  */
  33.  
  34. kern_return_t
  35. _S_get_init_port (mach_port_t msgport, mach_port_t auth, int which,
  36.           mach_port_t *result, mach_msg_type_name_t *result_type)
  37. {
  38.   AUTHCHECK;
  39.   *result_type = MACH_MSG_TYPE_MOVE_SEND;
  40.   /* This function adds a new user reference for the *RESULT it gives back.
  41.      Our reply message uses a move-send right that consumes this reference.  */
  42.   return _hurd_ports_get (which, result);
  43. }
  44.  
  45. kern_return_t
  46. _S_set_init_port (mach_port_t msgport, mach_port_t auth,
  47.           int which, mach_port_t port)
  48. {
  49.   error_t err;
  50.  
  51.   AUTHCHECK;
  52.  
  53.   err = _hurd_ports_set (which, port);
  54.   if (err == 0)
  55.     __mach_port_deallocate (__mach_task_self (), port);
  56.  
  57.   return 0;
  58. }
  59.  
  60. kern_return_t
  61. _S_get_init_ports (mach_port_t msgport, mach_port_t auth,
  62.            mach_port_t **ports,
  63.            mach_msg_type_name_t *ports_type,
  64.            unsigned int *nports)
  65. {
  66.   unsigned int i;
  67.   error_t err;
  68.  
  69.   AUTHCHECK;
  70.  
  71.   if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) ports,
  72.                _hurd_nports * sizeof (mach_port_t), 1))
  73.     return err;
  74.   *nports = _hurd_nports;
  75.  
  76.   for (i = 0; i < _hurd_nports; ++i)
  77.     /* This function adds a new user ref for the *RESULT it gives back.
  78.        Our reply message uses move-send rights that consumes this ref.  */
  79.     if (err = _hurd_ports_get (i, &(*ports)[i]))
  80.       {
  81.     /* Died part way through.  Deallocate the ports already fetched.  */
  82.     while (i-- > 0)
  83.       __mach_port_deallocate (__mach_task_self (), (*ports)[i]);
  84.     __vm_deallocate (__mach_task_self (),
  85.              (vm_address_t) *ports,
  86.              *nports * sizeof (mach_port_t));
  87.     return err;
  88.       }
  89.  
  90.   *ports_type = MACH_MSG_TYPE_MOVE_SEND;
  91.   return 0;
  92. }
  93.  
  94. kern_return_t
  95. _S_set_init_ports (mach_port_t msgport, mach_port_t auth,
  96.            mach_port_t *ports, unsigned int nports)
  97. {
  98.   unsigned int i;
  99.   error_t err;
  100.  
  101.   AUTHCHECK;
  102.  
  103.   for (i = 0; i < _hurd_nports; ++i)
  104.     {
  105.       if (err = _hurd_ports_set (i, ports[i]))
  106.     return err;
  107.       else
  108.     __mach_port_deallocate (__mach_task_self (), ports[i]);
  109.     }
  110.  
  111.   return 0;
  112. }
  113.  
  114. /* Snarfing and frobbing the init ints.  */
  115.  
  116. static kern_return_t
  117. get_int (int which, int *value)
  118. {
  119.   switch (which)
  120.     {
  121.     case INIT_UMASK:
  122.       *value = _hurd_umask;
  123.       return 0;
  124.     case INIT_SIGMASK:
  125.       {
  126.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  127.     *value = ss->blocked;
  128.     __mutex_unlock (&ss->lock);
  129.     return 0;
  130.       }
  131.     case INIT_SIGPENDING:
  132.       {
  133.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  134.     *value = ss->pending;
  135.     __mutex_unlock (&ss->lock);
  136.     return 0;
  137.       }
  138.     case INIT_SIGIGN:
  139.       {
  140.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  141.     sigset_t ign;
  142.     int sig;
  143.     __sigemptyset (&ign);
  144.     for (sig = 1; sig < NSIG; ++sig)
  145.       if (ss->actions[sig].sa_handler == SIG_IGN)
  146.         __sigaddset (&ign, sig);
  147.     __mutex_unlock (&ss->lock);
  148.     *value = ign;
  149.     return 0;
  150.       }
  151.     default:
  152.       return EINVAL;
  153.     }
  154. }
  155.  
  156. kern_return_t
  157. _S_get_init_int (mach_port_t msgport, mach_port_t auth,
  158.          int which, int *value)
  159. {
  160.   AUTHCHECK;
  161.  
  162.   return get_int (which, value);
  163. }
  164.  
  165. kern_return_t
  166. _S_get_init_ints (mach_port_t msgport, mach_port_t auth,
  167.           int **values, unsigned int *nvalues)
  168. {
  169.   error_t err;
  170.   unsigned int i;
  171.  
  172.   AUTHCHECK;
  173.  
  174.   if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) values,
  175.                INIT_INT_MAX * sizeof (int), 1))
  176.     return err;
  177.   *nvalues = INIT_INT_MAX;
  178.  
  179.   for (i = 0; i < INIT_INT_MAX; ++i)
  180.     switch (err = get_int (i, &(*values)[i]))
  181.       {
  182.       case 0:            /* Success.  */
  183.     break;
  184.       case EINVAL:        /* Unknown index.  */
  185.     (*values)[i] = 0;
  186.     break;
  187.       default:            /* Lossage.  */
  188.     __vm_deallocate (__mach_task_self (),
  189.              (vm_address_t) *values, INIT_INT_MAX * sizeof (int));
  190.     return err;
  191.       }
  192.  
  193.   return 0;
  194. }
  195.  
  196.  
  197. static kern_return_t
  198. set_int (int which, int value)
  199. {
  200.   switch (which)
  201.     {
  202.     case INIT_UMASK:
  203.       _hurd_umask = value;
  204.       return 0;
  205.  
  206.       /* These are pretty odd things to do.  But you asked for it.  */
  207.     case INIT_SIGMASK:
  208.       {
  209.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  210.     ss->blocked = value;
  211.     __mutex_unlock (&ss->lock);
  212.     return 0;
  213.       }
  214.     case INIT_SIGPENDING:
  215.       {
  216.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  217.     ss->pending = value;
  218.     __mutex_unlock (&ss->lock);
  219.     return 0;
  220.       }
  221.     case INIT_SIGIGN:
  222.       {
  223.     struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
  224.     int sig;
  225.     const sigset_t ign = value;
  226.     for (sig = 1; sig < NSIG; ++sig)
  227.       {
  228.         if (__sigismember (&ign, sig))
  229.           ss->actions[sig].sa_handler = SIG_IGN;
  230.         else if (ss->actions[sig].sa_handler == SIG_IGN)
  231.           ss->actions[sig].sa_handler = SIG_DFL;
  232.       }
  233.     __mutex_unlock (&ss->lock);
  234.     return 0;
  235.       }
  236.     default:
  237.       return EINVAL;
  238.     }
  239. }
  240.  
  241. kern_return_t
  242. _S_set_init_int (mach_port_t msgport, mach_port_t auth,
  243.          int which, int value)
  244. {
  245.   AUTHCHECK;
  246.  
  247.   return set_int (which, value);
  248. }
  249.  
  250. kern_return_t
  251. _S_set_init_ints (mach_port_t msgport, mach_port_t auth,
  252.           int *values, unsigned int nvalues)
  253. {
  254.   error_t err;
  255.   unsigned int i;
  256.  
  257.   AUTHCHECK;
  258.  
  259.   for (i = 0; i < INIT_INT_MAX; ++i)
  260.     switch (err = set_int (i, values[i]))
  261.       {
  262.       case 0:            /* Success.  */
  263.     break;
  264.       case EINVAL:        /* Unknown index.  */
  265.     break;
  266.       default:            /* Lossage.  */
  267.     return err;
  268.       }
  269.  
  270.   return 0;
  271. }
  272.  
  273.  
  274. kern_return_t
  275. _S_get_fd (mach_port_t msgport, mach_port_t auth,
  276.        int which, mach_port_t *result, mach_msg_type_name_t *result_type)
  277. {
  278.   AUTHCHECK;
  279.  
  280.   /* This creates a new user reference for the send right.
  281.      Our reply message will move that reference to the caller.  */
  282.   *result = __getdport (which);
  283.   if (*result == MACH_PORT_NULL)
  284.     return errno;
  285.   *result_type = MACH_MSG_TYPE_MOVE_SEND;
  286.  
  287.   return 0;
  288. }
  289.  
  290. kern_return_t
  291. _S_set_fd (mach_port_t msgport, mach_port_t auth,
  292.        int which, mach_port_t port)
  293. {
  294.   AUTHCHECK;
  295.  
  296.   /* We consume the reference if successful.  */
  297.   return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
  298. }
  299.  
  300. /* Snarfing and frobbing environment variables.  */
  301.  
  302. kern_return_t
  303. _S_get_env_variable (mach_port_t msgport,
  304.              char *variable,
  305.              char **data, unsigned int *datalen)
  306. {
  307.   const char *value = getenv (variable);
  308.  
  309.   if (value == NULL)
  310.     return ENOENT;
  311.  
  312.   /* XXX this pointer might become invalid */
  313.   *data = value;
  314.   *datalen = strlen (value);
  315.   return 0;
  316. }
  317.  
  318.  
  319. kern_return_t
  320. _S_set_env_variable (mach_port_t msgport, mach_port_t auth,
  321.              char *variable,
  322.              char *value,
  323.              int replace)
  324. {
  325.   AUTHCHECK;
  326.  
  327.   if (setenv (variable, value, replace)) /* XXX name space */
  328.     return errno;
  329.   return 0;
  330. }
  331.  
  332. kern_return_t
  333. _S_get_environment (mach_port_t msgport,
  334.             char **data, unsigned int *datalen)
  335. {
  336.   /* Pack the environment into an array with nulls separating elements.  */
  337.   if (__environ != NULL)
  338.     {
  339.       char *ap, **p;
  340.       size_t envlen = 0;
  341.  
  342.       for (p = __environ; *p != NULL; ++p)
  343.     envlen += strlen (*p) + 1;
  344.  
  345.       if (envlen > *datalen)
  346.     {
  347.       if (__vm_allocate (__mach_task_self (),
  348.                  (vm_address_t *) data, envlen, 1))
  349.         return ENOMEM;
  350.     }
  351.  
  352.       ap = *data;
  353.       for (p = __environ; *p != NULL; ++p)
  354.     ap = __memccpy (ap, *p, '\0', ULONG_MAX);
  355.  
  356.       *datalen = envlen;
  357.     }
  358.   else
  359.     *datalen = 0;
  360.  
  361.   return 0;
  362. }
  363.  
  364. kern_return_t
  365. _S_set_environment (mach_port_t msgport, mach_port_t auth,
  366.             char *data, unsigned int datalen)
  367. {
  368.   int _hurd_split_args (char *, unsigned int, char **);
  369.   int envc;
  370.   char **envp;
  371.  
  372.   AUTHCHECK;
  373.  
  374.   envc = _hurd_split_args (data, datalen, NULL);
  375.   envp = malloc ((envc + 1) * sizeof (char *));
  376.   if (envp == NULL)
  377.     return errno;
  378.   _hurd_split_args (data, datalen, envp);
  379.   __environ = envp;        /* XXX cooperate with loadenv et al */
  380.   return 0;
  381. }
  382.  
  383.  
  384.  
  385. /* XXX */
  386.  
  387. kern_return_t
  388. _S_get_dtable (mach_port_t process,
  389.            mach_port_t refport,
  390.            portarray_t *dtable,
  391.            mach_msg_type_name_t *dtablePoly,
  392.            mach_msg_type_number_t *dtableCnt)
  393. { return EOPNOTSUPP; }
  394.  
  395. kern_return_t
  396. _S_set_dtable (mach_port_t process,
  397.            mach_port_t refport,
  398.            portarray_t dtable,
  399.            mach_msg_type_number_t dtableCnt)
  400. { return EOPNOTSUPP; }
  401.  
  402. kern_return_t
  403. _S_io_select_done (mach_port_t notify_port,
  404.            mach_msg_type_name_t notify_port_type,
  405.            int select_result,
  406.            int id_tag)
  407. { return EOPNOTSUPP; }
  408.  
  409. kern_return_t
  410. _S_startup_dosync (mach_port_t process)
  411. { return EOPNOTSUPP; }
  412.  
  413. kern_return_t
  414. _S_dir_changed (mach_port_t notify_port,
  415.         dir_changed_type_t change,
  416.         string_t name)
  417. { return EOPNOTSUPP; }
  418.  
  419. kern_return_t
  420. _S_file_changed (mach_port_t notify_port,
  421.          file_changed_type_t change,
  422.          off_t start,
  423.          off_t end)
  424. { return EOPNOTSUPP; }
  425.